package com.rzcoding.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.rzcoding.service.AuthService;
import com.rzcoding.util.AuthToken;
import com.rzcoding.util.HttpClient;
import okhttp3.FormBody;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.loadbalancer.LoadBalancerClient;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.net.URI;
import java.util.concurrent.TimeUnit;

@Service
public class AuthServiceImpl implements AuthService {

    @Autowired
    private LoadBalancerClient loadBalancerClient;

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @Value("${auth.ttl}")
    private long ttl;

    @Value("${spring.application.name}")
    private String appName;

    @Override
    public AuthToken login(String username, String password, String clientId, String clientSecret) {
        //1.申请令牌
        ServiceInstance serviceInstance = loadBalancerClient.choose(appName);
        URI uri = serviceInstance.getUri();
        String url = uri + "/oauth/token";

        FormBody body = new FormBody.Builder()
                .add("grant_type", "password")
                .add("username", username)
                .add("password", password)
                .add("client_id", clientId)
                .add("client_secret", clientSecret)
                .build();
        try {
            String respStr = HttpClient.httpPost4form(url, body);
            JSONObject resp = JSON.parseObject(respStr, JSONObject.class);
            if (resp.get("access_token") == null || resp.get("refresh_token") == null || resp.get("jti") == null) {
                //申请令牌失败
                throw new RuntimeException("申请令牌失败");
            }
            //2.封装结果数据
            AuthToken authToken = new AuthToken();
            authToken.setAccessToken(resp.getString("access_token"));
            authToken.setRefreshToken(resp.getString("refresh_token"));
            authToken.setJti(resp.getString("jti"));

            //3.将jti作为redis中的key,将jwt作为redis中的value进行数据的存放
            stringRedisTemplate.boundValueOps(authToken.getJti()).set(authToken.getAccessToken(), ttl, TimeUnit.SECONDS);
            return authToken;
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException("申请令牌失败");
        }
    }
}
